<!DOCTYPE html><html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/extjs/6.2.0/ext-modern-all-debug.js"></script>

    <link rel="stylesheet" type="text/css" href="http://cdnjs.cloudflare.com/ajax/libs/extjs/6.2.0/modern/theme-material/resources/theme-material-all-debug.css">
    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/extjs/6.2.0/modern/theme-material/theme-material-debug.js"></script>

    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/extjs/6.2.0/packages/charts/classic/classic/resources/charts-all-debug.css">
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/extjs/6.2.0/packages/charts/modern/charts-debug.js"></script>

    <script type="text/javascript">
    Ext.define('MyApp.view.ToolsController', {
      extend: 'Ext.app.ViewController',
      alias: 'controller.tools',

      onPaletteChange: function(c, v) {
        var c = this.lookupReference('palette');
        c.setActiveItem(v.data.value);
      },

      onColorChange: function(v,fs) {
        var p = this.lookupReference('canvas');
        p.value = v;
        p.fillStyle = fs;
      },

      onSizeChange: function() {
        var h = parseInt(this.lookupReference('height').getValue());
        var w = parseInt(this.lookupReference('width').getValue());

        var s = 512 / Math.max(h,w);

        var sprites = [];
        for (var x = 0; x < w; x++) {
          for (var y = 0; y < h; y++) {
            sprites.push({ type: 'rect', 'x': x*s, 'y': y*s, i: (y*w)+x, width: s, height:s, fillStyle: '#000', strokeStyle: '#ccc' })
          }
        }

        var c = this.lookupReference('canvas');
        c.getSurface().removeAll();
        c.getSurface().add(sprites);
        c.getSurface().renderFrame();
      }

    });

    Ext.application({
        name: 'icon editor',

        launch: function() {
          Ext.Viewport.setController('tools');
            Ext.Viewport.add([{
              xtype: 'toolbar',
              docked: 'top',
              title: 'Icon Editor',
              items: [{
                xtype: 'button',
                iconCls: 'x-fa fa-step-backward'
              },{
                xtype: 'button',
                iconCls: 'x-fa fa-play'
              },{
                xtype: 'button',
                iconCls: 'x-fa fa-step-forward'
              },{
                xtype: 'button',
                iconCls: 'x-fa fa-arrow-up'
              },{
                xtype: 'button',
                iconCls: 'x-fa fa-arrow-down'
              },{
                xtype: 'button',
                iconCls: 'x-fa fa-plus'
              },{
                xtype: 'button',
                iconCls: 'x-fa fa-minus'
              },{
                xtype: 'button',
                iconCls: 'x-fa fa-trash-o'
              },{
                xtype: 'button',
                iconCls: 'x-fa fa-hdd-o'
              }]
            },{
              xtype: 'panel',
              layout: 'hbox',
              padding: 0,
              items: [{
                padding: 0,
                border: true,
                xtype: 'panel',
                layout: 'vbox',
                width: 250,
                items: [{
                  xtype: 'formpanel',
                  items: [{
                    xtype: 'textfield',
                    reference: 'ip',
                    label: 'Device IP'
                  },{
                    xtype: 'fieldset',
                    title: 'Image',
                    items: [{
                      xtype: 'textfield',
                      reference: 'width',
                      label: 'Width',
                      value: '16',
                      required: true,
                      listeners: {
                        change: 'onSizeChange'
                      }
                    },{
                      xtype: 'textfield',
                      reference: 'height',
                      label: 'Height',
                      value: '16',
                      required: true,
                      listeners: {
                        change: 'onSizeChange'
                      }
                    },{
                      xtype: 'selectfield',
                      reference: 'selectpalette',
                      label: 'Palette',
                      value: 3,
                      options: [{
                        text: '1 bpp: monochrome',
                        value: 0
                      },{
                        text: '4 bpp: 16 grays',
                        value: 1
                      },{
                        text: '4 bpp: 16 colours',
                        value: 2
                      },{
                        text: '8 bpp: 64 colours',
                        value: 3
                      }],
                      listeners: {
                        change: 'onPaletteChange'
                      }
                    }]
                  },{
                    xtype: 'fieldset',
                    title: 'Frame',
                    items: [{
                      xtype: 'sliderfield',
                      reference: 'delay',
                      label: 'Delay',
                      value: 0,
                      minValue: 0,
                      maxValue: 63
                    }]
                  },{
                    xtype: 'fieldset',
                    title: 'Pixel',
                    items: [{
                      xtype: 'panel',
                      layout: 'card',
                      reference: 'palette',
                      label: 'Colour',
                      height: 200,
                      activeItem: 3,
                      items: [{
                        xtype: 'palette0',
                        listeners: {change: 'onColorChange'}
                      },{
                        xtype: 'palette1',
                        listeners: {change: 'onColorChange'}
                      },{
                        xtype: 'palette2',
                        listeners: {change: 'onColorChange'}
                      },{
                        xtype: 'palette3',
                        listeners: {change: 'onColorChange'}
                      }]
                    }]
                  }]
                }]
            },{
              xtype: 'panel',
              flex: 1,
              border: true,
              items: [{
                xtype: 'draw',
                plugins: ['spriteevents'],
                color: '#ccc',
                reference: 'canvas',
                centered: true,
                border: true,
                width: 512,
                height: 512,
                fillStyle: '#000',
                color: 0,
                listeners: {
                  spriteclick: function (item, event) {
                    var sprite = item && item.sprite;
                    if (sprite) {
                      sprite.setAttributes({fillStyle: this.fillStyle, value: this.value});
                      sprite.getSurface().renderFrame();
                    }
                  }
                }
              }]
            },{
              border: true,
              xtype: 'panel',
              layout: 'fit',
              width: 100,
              items: [{
                xtype: 'list',
                itemTpl: '{title}',
                data: [
                  { title: 'Item 1' },
                  { title: 'Item 2' },
                  { title: 'Item 3' },
                  { title: 'Item 4' }
                ]
              }]
            }
          ]
        }]);
      }
    });

    Ext.define('MyApp.view.Palette0', {
      extend: 'Ext.draw.Container',
      alias: 'widget.palette0',
      plugins: ['spriteevents'],
      sprites: [
        { type: 'hexagon', x: 80, y: 20, l: 39, fillStyle: '#fff', strokeStyle: '#aaa', value: 1 },
        { type: 'hexagon', x: 160, y: 20, l: 39, fillStyle: '#000', value: 0 },
      ],
      listeners: {
        spriteclick: function (item, event) {
          var sprite = item && item.sprite;
          if (sprite) {
            this.fireEvent('change', sprite.value, sprite.fillStyle)
          }
        }
      }
    });

    Ext.define('MyApp.view.Palette1', {
      extend: 'Ext.draw.Container',
      alias: 'widget.palette1',
      plugins: ['spriteevents'],
      sprites: [
        { type: 'hexagon', x: 70, y: 10, l: 19, fillStyle: '#000', value: 0 },
        { type: 'hexagon', x: 50, y: 40, l: 19, fillStyle: '#111', value: 1 },
        { type: 'hexagon', x: 30, y: 70, l: 19, fillStyle: '#222', value: 2 },
        { type: 'hexagon', x: 50, y: 100, l: 19, fillStyle: '#333', value: 3 },
        { type: 'hexagon', x: 70, y: 70, l: 19, fillStyle: '#444', value: 4 },
        { type: 'hexagon', x: 90, y: 40, l: 19, fillStyle: '#555', value: 5 },
        { type: 'hexagon', x: 110, y: 10, l: 19, fillStyle: '#666', value: 6 },
        { type: 'hexagon', x: 150, y: 10, l: 19, fillStyle: '#777', value: 7 },
        { type: 'hexagon', x: 130, y: 40, l: 19, fillStyle: '#888', value: 8 },
        { type: 'hexagon', x: 110, y: 70, l: 19, fillStyle: '#999', value: 9 },
        { type: 'hexagon', x: 90, y: 100, l: 19, fillStyle: '#aaa', value: 10 },
        { type: 'hexagon', x: 130, y: 100, l: 19, fillStyle: '#bbb', value: 11 },
        { type: 'hexagon', x: 150, y: 70, l: 19, fillStyle: '#ccc', value: 12 },
        { type: 'hexagon', x: 170, y: 40, l: 19, fillStyle: '#ddd', value: 13 },
        { type: 'hexagon', x: 190, y: 70, l: 19, fillStyle: '#eee', value: 14 },
        { type: 'hexagon', x: 170, y: 100, l: 19, fillStyle: '#fff', value: 15, strokeStyle: '#aaa' },
      ],
      listeners: {
        spriteclick: function (item, event) {
          var sprite = item && item.sprite;
          if (sprite) {
            this.fireEvent('change', sprite.value, sprite.fillStyle)
          }
        }
      }
    });

    Ext.define('MyApp.view.Palette2', {
      extend: 'Ext.draw.Container',
      alias: 'widget.palette2',
      plugins: ['spriteevents'],
      sprites: [
        { type: 'hexagon', x: 150, y: 70, l: 19, fillStyle: '#f55', value: 4 },
    		{ type: 'hexagon', x: 190, y: 70, l: 19, fillStyle: '#a00', value: 12 },
    		{ type: 'hexagon', x: 130, y: 40, l: 19, fillStyle: '#ff5', value: 6 },
    		{ type: 'hexagon', x: 150, y: 10, l: 19, fillStyle: '#a50', value: 14 },
    		{ type: 'hexagon', x: 90, y: 40, l: 19, fillStyle: '#5f5', value: 2 },
    		{ type: 'hexagon', x: 70, y: 10, l: 19, fillStyle: '#0a0', value: 10 },
        { type: 'hexagon', x: 70, y: 70, l: 19, fillStyle: '#5ff', value: 3 },
    		{ type: 'hexagon', x: 30, y: 70, l: 19, fillStyle: '#0aa', value: 11 },
        { type: 'hexagon', x: 90, y: 100, l: 19, fillStyle: '#55f', value: 1 },
    		{ type: 'hexagon', x: 70, y: 130, l: 19, fillStyle: '#00a', value: 9 },
    		{ type: 'hexagon', x: 130, y: 100, l: 19, fillStyle: '#f5f', value: 5 },
        { type: 'hexagon', x: 150, y: 130, l: 19, fillStyle: '#a0a', value: 13 },
    		{ type: 'hexagon', x: 50, y: 100, l: 19, fillStyle: '#000', value: 0 },
    		{ type: 'hexagon', x: 170, y: 100, l: 19, fillStyle: '#555', value: 8 },
    		{ type: 'hexagon', x: 110, y: 10, l: 19, fillStyle: '#aaa', value: 7 },
    		{ type: 'hexagon', x: 110, y: 70, l: 19, fillStyle: '#fff', value: 15, strokeStyle: '#aaa' }
      ],
      listeners: {
        spriteclick: function (item, event) {
          var sprite = item && item.sprite;
          if (sprite) {
            this.fireEvent('change', sprite.value, sprite.fillStyle)
          }
        }
      }
    });

    Ext.define('MyApp.view.Palette3', {
      extend: 'Ext.draw.Container',
      alias: 'widget.palette3',
      plugins: ['spriteevents'],
      initialize: function() {
        var sprites_x = [
          { type: 'hexagon', x: 40, y: 100, l: 19, fillStyle: '#000', value: 0 },
          { type: 'hexagon', x: 190, y: 100, l: 19, fillStyle: '#555', value: 21 },
          { type: 'hexagon', x: 190, y: 30, l: 19, fillStyle: '#aaa', value: 42 },
          { type: 'hexagon', x: 40, y: 30, l: 19, fillStyle: '#fff', strokeStyle: '#aaa', value: 63 }
        ];

        this.sprites_f = [
          { type: 'hexagon', x: 130, y: 70, l: 9, fillStyle: '#faa', value: 58 },
          { type: 'hexagon', x: 150, y: 70, l: 9, fillStyle: '#f55', value: 53 },
          { type: 'hexagon', x: 170, y: 70, l: 9, fillStyle: '#f00', value: 48 },

          { type: 'hexagon', x: 140, y: 55, l: 9, fillStyle: '#fa5', value: 57 },
          { type: 'hexagon', x: 150, y: 40, l: 9, fillStyle: '#fa0', value: 56 },
          { type: 'hexagon', x: 160, y: 55, l: 9, fillStyle: '#f50', value: 52 },

          { type: 'hexagon', x: 120, y: 55, l: 9, fillStyle: '#ffa', value: 62 },
          { type: 'hexagon', x: 130, y: 40, l: 9, fillStyle: '#ff5', value: 61 },
          { type: 'hexagon', x: 140, y: 25, l: 9, fillStyle: '#ff0', value: 60 },

          { type: 'hexagon', x: 110, y: 40, l: 9, fillStyle: '#af5', value: 45 },
          { type: 'hexagon', x: 120, y: 25, l: 9, fillStyle: '#af0', value: 44 },
          { type: 'hexagon', x: 100, y: 25, l: 9, fillStyle: '#5f0', value: 28 },

          { type: 'hexagon', x: 100, y: 55, l: 9, fillStyle: '#afa', value: 46 },
          { type: 'hexagon', x: 90, y: 40, l: 9, fillStyle: '#5f5', value: 29 },
          { type: 'hexagon', x: 80, y: 25, l: 9, fillStyle: '#0f0', value: 12 },

          { type: 'hexagon', x: 80, y: 55, l: 9, fillStyle: '#5fa', value: 30 },
          { type: 'hexagon', x: 60, y: 55, l: 9, fillStyle: '#0fa', value: 14 },
          { type: 'hexagon', x: 70, y: 40, l: 9, fillStyle: '#0f5', value: 13 },

          { type: 'hexagon', x: 90, y: 70, l: 9, fillStyle: '#aff', value: 47 },
          { type: 'hexagon', x: 70, y: 70, l: 9, fillStyle: '#5ff', value: 31 },
          { type: 'hexagon', x: 50, y: 70, l: 9, fillStyle: '#0ff', value: 15 },

          { type: 'hexagon', x: 80, y: 85, l: 9, fillStyle: '#5af', value: 27 },
          { type: 'hexagon', x: 60, y: 85, l: 9, fillStyle: '#0af', value: 11 },
          { type: 'hexagon', x: 70, y: 100, l: 9, fillStyle: '#05f', value: 7 },

          { type: 'hexagon', x: 100, y: 85, l: 9, fillStyle: '#aaf', value: 43 },
          { type: 'hexagon', x: 90, y: 100, l: 9, fillStyle: '#55f', value: 23 },
          { type: 'hexagon', x: 80, y: 115, l: 9, fillStyle: '#00f', value: 3 },

          { type: 'hexagon', x: 110, y: 100, l: 9, fillStyle: '#a5f', value: 39 },
          { type: 'hexagon', x: 120, y: 115, l: 9, fillStyle: '#a0f', value: 35 },
          { type: 'hexagon', x: 100, y: 115, l: 9, fillStyle: '#50f', value: 19 },

          { type: 'hexagon', x: 120, y: 85, l: 9, fillStyle: '#faf', value: 59 },
          { type: 'hexagon', x: 130, y: 100, l: 9, fillStyle: '#f5f', value: 55 },
          { type: 'hexagon', x: 140, y: 115, l: 9, fillStyle: '#f0f', value: 51 },

          { type: 'hexagon', x: 140, y: 85, l: 9, fillStyle: '#f5a', value: 54 },
          { type: 'hexagon', x: 150, y: 100, l: 9, fillStyle: '#f0a', value: 50 },
          { type: 'hexagon', x: 160, y: 85, l: 9, fillStyle: '#f05', value: 49 },

          { type: 'hexagon', x: 110, y: 70, l: 9, fillStyle: '#fff', strokeStyle: '#aaa', value: 63 }
        ].concat(sprites_x);
        this.sprites_a = [
          { type: 'hexagon', x: 130, y: 70, l: 9, fillStyle: '#a55', value: 37 },
          { type: 'hexagon', x: 120, y: 55, l: 9, fillStyle: '#aa5', value: 41 },
          { type: 'hexagon', x: 100, y: 55, l: 9, fillStyle: '#5a5', value: 25 },
          { type: 'hexagon', x: 90, y: 70, l: 9, fillStyle: '#5aa', value: 26 },
          { type: 'hexagon', x: 100, y: 85, l: 9, fillStyle: '#55a', value: 22 },
          { type: 'hexagon', x: 120, y: 85, l: 9, fillStyle: '#a5a', value: 38 },
          { type: 'hexagon', x: 110, y: 70, l: 9, fillStyle: '#aaa', value: 42 }
        ].concat(sprites_x);
        this.sprites_5 = [
          { type: 'hexagon', x: 130, y: 70, l: 9, fillStyle: '#a55', value: 37 },
          { type: 'hexagon', x: 120, y: 55, l: 9, fillStyle: '#aa5', value: 41 },
          { type: 'hexagon', x: 100, y: 55, l: 9, fillStyle: '#5a5', value: 25 },
          { type: 'hexagon', x: 90, y: 70, l: 9, fillStyle: '#5aa', value: 26 },
          { type: 'hexagon', x: 100, y: 85, l: 9, fillStyle: '#55a', value: 22 },
          { type: 'hexagon', x: 120, y: 85, l: 9, fillStyle: '#a5a', value: 38 },
          { type: 'hexagon', x: 110, y: 70, l: 9, fillStyle: '#555', value: 21 }
        ].concat(sprites_x);
        this.sprites_0 = [
          { type: 'hexagon', x: 130, y: 70, l: 9, fillStyle: '#500', value: 16 },
          { type: 'hexagon', x: 150, y: 70, l: 9, fillStyle: '#a00', value: 32 },
          { type: 'hexagon', x: 170, y: 70, l: 9, fillStyle: '#f00', value: 48 },

          { type: 'hexagon', x: 140, y: 55, l: 9, fillStyle: '#a50', value: 36 },
          { type: 'hexagon', x: 160, y: 55, l: 9, fillStyle: '#f50', value: 52 },
          { type: 'hexagon', x: 150, y: 40, l: 9, fillStyle: '#fa0', value: 56 },

          { type: 'hexagon', x: 120, y: 55, l: 9, fillStyle: '#550', value: 20 },
          { type: 'hexagon', x: 130, y: 40, l: 9, fillStyle: '#aa0', value: 40 },
          { type: 'hexagon', x: 140, y: 25, l: 9, fillStyle: '#ff0', value: 60 },

          { type: 'hexagon', x: 110, y: 40, l: 9, fillStyle: '#5a0', value: 24 },
          { type: 'hexagon', x: 100, y: 25, l: 9, fillStyle: '#5f0', value: 28 },
          { type: 'hexagon', x: 120, y: 25, l: 9, fillStyle: '#af0', value: 44 },

          { type: 'hexagon', x: 100, y: 55, l: 9, fillStyle: '#050', value: 4 },
          { type: 'hexagon', x: 90, y: 40, l: 9, fillStyle: '#0a0', value: 8 },
          { type: 'hexagon', x: 80, y: 25, l: 9, fillStyle: '#0f0', value: 12 },

          { type: 'hexagon', x: 80, y: 55, l: 9, fillStyle: '#0a5', value: 9 },
          { type: 'hexagon', x: 70, y: 40, l: 9, fillStyle: '#0f5', value: 13 },
          { type: 'hexagon', x: 60, y: 55, l: 9, fillStyle: '#0fa', value: 14 },

          { type: 'hexagon', x: 90, y: 70, l: 9, fillStyle: '#055', value: 5 },
          { type: 'hexagon', x: 70, y: 70, l: 9, fillStyle: '#0aa', value: 10 },
          { type: 'hexagon', x: 50, y: 70, l: 9, fillStyle: '#0ff', value: 15 },

          { type: 'hexagon', x: 80, y: 85, l: 9, fillStyle: '#05a', value: 6 },
          { type: 'hexagon', x: 70, y: 100, l: 9, fillStyle: '#05f', value: 7 },
          { type: 'hexagon', x: 60, y: 85, l: 9, fillStyle: '#0af', value: 11 },

          { type: 'hexagon', x: 100, y: 85, l: 9, fillStyle: '#005', value: 1 },
          { type: 'hexagon', x: 90, y: 100, l: 9, fillStyle: '#00a', value: 2 },
          { type: 'hexagon', x: 80, y: 115, l: 9, fillStyle: '#00f', value: 3 },

          { type: 'hexagon', x: 110, y: 100, l: 9, fillStyle: '#50a', value: 18 },
          { type: 'hexagon', x: 100, y: 115, l: 9, fillStyle: '#50f', value: 19 },
          { type: 'hexagon', x: 120, y: 115, l: 9, fillStyle: '#a0f', value: 35 },

          { type: 'hexagon', x: 120, y: 85, l: 9, fillStyle: '#505', value: 17 },
          { type: 'hexagon', x: 130, y: 100, l: 9, fillStyle: '#a0a', value: 34 },
          { type: 'hexagon', x: 140, y: 115, l: 9, fillStyle: '#f0f', value: 51 },

          { type: 'hexagon', x: 140, y: 85, l: 9, fillStyle: '#a05', value: 33 },
          { type: 'hexagon', x: 160, y: 85, l: 9, fillStyle: '#f05', value: 49 },
          { type: 'hexagon', x: 150, y: 100, l: 9, fillStyle: '#f0a', value: 50 },

          { type: 'hexagon', x: 110, y: 70, l: 9, fillStyle: '#000', value: 0 }
        ].concat(sprites_x);

        this.callParent();
        this.setSprites(this.sprites_f);
      },
      listeners: {
        spriteclick: function (item, event) {
          var sprite = item && item.sprite;
          if (sprite) {
            if (sprite.value == 63) {
              this.getSurface().removeAll();
              this.getSurface().add(this.sprites_f);
              this.getSurface().renderFrame();
            } else if (sprite.value == 42) {
              this.getSurface().removeAll();
              this.getSurface().add(this.sprites_a);
              this.getSurface().renderFrame();
            } else if (sprite.value == 21) {
              this.getSurface().removeAll();
              this.getSurface().add(this.sprites_5);
              this.getSurface().renderFrame();
            } else if (sprite.value == 0) {
              this.getSurface().removeAll();
              this.getSurface().add(this.sprites_0);
              this.getSurface().renderFrame();
            }
            this.fireEvent('change', sprite.value, sprite.fillStyle)
         }
       }
     }
    });

    Ext.define('Icon.sprite.Hexagon', {
        extend: 'Ext.draw.sprite.Path',
        alias: 'sprite.hexagon',
        type: 'hexagon',
        inheritableStatics: {
            def: {
                processors: {
                    x: 'number',
                    y: 'number',
                    l: 'number'
                },
                aliases: {
                },
                triggers: {
                    x: 'path',
                    y: 'path',
                    l: 'path'
                },
                defaults: {
                    x: 0,
                    y: 0,
                    l: 9
                }
            }
        },
        updatePath: function (path, attr) {
            var x = attr.x,
                y = attr.y,
                l = attr.l,        // side length
                h = attr.l / 2;    // half side length

            path.fromSvgString('M'.concat(x-h, ',', y-h, 'l', [l, h, 0, l, -l, h, -l, -h, 0, -l, 'z']));
        }
    });
    </script>
</head>
<body>
</body>
</html>
